package org.budo.oceanengine.api.impl;

import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.budo.oceanengine.api.OceanengineApi;
import org.budo.oceanengine.api.entity.AccessTokenResponse;
import org.budo.oceanengine.api.entity.Advertiser;
import org.budo.oceanengine.api.entity.BaseRequest;
import org.budo.oceanengine.api.entity.BaseResponse;
import org.budo.oceanengine.api.entity.OceanengineConfig;
import org.budo.oceanengine.api.entity.RefreshTokenResponse;
import org.budo.oceanengine.api.entity.UserInfo;
import org.budo.oceanengine.api.util.RequestHandler;
import org.budo.support.fastjson.Fastjson;
import org.budo.support.http.client.Request;
import org.budo.support.http.client.Response;

import java.util.List;
import java.util.Map;

/**
 *
 * 巨量引擎平台接口
 *
 * @author zhangqian
 * @createDate: 2021/4/15 16:31
 * @version: 1.0
 */
@Slf4j
@Getter
@Setter
@NoArgsConstructor
public class OceanengineApiImpl implements OceanengineApi {
    private String appKey;

    private String appSecret;

    public OceanengineApiImpl(String appKey, String appSecret) {
        this.appKey = appKey;
        this.appSecret = appSecret;
    }

    @Override
    public BaseResponse createAdvertiser(OceanengineConfig config, String accessToken, Map<String, Object> paramMap) {
        BaseRequest request = new BaseRequest();
        request.setBaseUrl(config.getBaseUrl());
        request.setApiUri("/2/agent/advertiser/create_v2/");

        request.setAccessToken(accessToken);

        request.setParamMap(paramMap);

        return RequestHandler.doPost(request);
    }

    @Override
    public BaseResponse getAdvertiserInfo(OceanengineConfig config, String accessToken, List<Long> advertiserIds) {
        BaseRequest request = new BaseRequest();
        request.setBaseUrl(config.getBaseUrl());
        request.setApiUri("/2/advertiser/info/");

        request.setAccessToken(accessToken);

        request.getParamMap().put("advertiser_ids", advertiserIds);

        return RequestHandler.doGet(request);
    }

    @Override
    public AccessTokenResponse accessToken(String authCode) {
        Request request = new Request();
        request.setUrl("https://ad.oceanengine.com/open_api/oauth2/access_token/");
        request.setMethod(Request.POST);
        request.setContentType("application/json");
        request.setParameter("app_id", this.getAppKey());
        request.setParameter("secret", this.getAppSecret());
        request.setParameter("grant_type", "auth_code");
        request.setParameter("auth_code", authCode);
        Response response = request.execute();

        String responseBody = response.bodyOrToString();
        if (null == responseBody || !responseBody.trim().startsWith("{")) {
            log.error("#82 accessToken, response=" + response + ", request=" + request);
            return null;
        }

        JSONObject responseObject = Fastjson.parseObject(responseBody);
        JSONObject data = responseObject.getJSONObject("data");
        if (null == data || data.isEmpty()) {
            log.error("#91 accessToken, response=" + response + ", request=" + request);
            return null;
        }

        log.info("#99 accessToken, response=" + response + ", request=" + request);

        return new AccessTokenResponse() //
                .setResponseBody(responseBody) //
                .setAdvertiserId(data.getString("advertiser_id")) //
                .setAdvertiserName(data.getString("advertiser_name")) //
                .setAccessToken(data.getString("access_token")) //
                .setExpiresIn(data.getLong("expires_in")) // access_token剩余有效时间,单位(秒)
                .setRefreshToken(data.getString("refresh_token")) //
                .setRefreshTokenExpiresIn(data.getLong("refresh_token_expires_in")); // refresh_token剩余有效时间,单位(秒)
    }

    @Override
    public RefreshTokenResponse refreshToken(String refreshToken) {
        Request request = new Request();
        request.setUrl("https://ad.oceanengine.com/open_api/oauth2/refresh_token/");
        request.setMethod(Request.POST);
        request.setContentType("application/json");
        request.setParameter("app_id", this.getAppKey());
        request.setParameter("secret", this.getAppSecret());
        request.setParameter("grant_type", "refresh_token");
        request.setParameter("refresh_token", refreshToken);
        Response response = request.execute();

        String responseBody = response.bodyOrToString();
        if (null == responseBody || !responseBody.trim().startsWith("{")) {
            log.error("#125 refreshToken, response=" + response + ", request=" + request);
            return null;
        }

        JSONObject responseObject = Fastjson.parseObject(responseBody);
        JSONObject data = responseObject.getJSONObject("data");
        if (null == data || data.isEmpty()) {
            log.error("#132 refreshToken, response=" + response + ", request=" + request);
            return null;
        }

        log.info("#136 refreshToken, response=" + response + ", request=" + request);

        return new RefreshTokenResponse() //
                .setResponseBody(responseBody) //
                .setAccessToken(data.getString("access_token")) //
                .setExpiresIn(data.getLong("expires_in")) //
                .setRefreshToken(data.getString("refresh_token")) //
                .setRefreshTokenExpiresIn(data.getLong("refresh_token_expires_in"));
    }

    @Override
    public Advertiser getAdvertiser(String accessToken) {
        return null;
    }

    @Override
    public UserInfo userInfo(String accessToken) {
        return null;
    }

    @Override
    public BaseResponse getIndustryList(OceanengineConfig config, String accessToken, Map<String, Object> paramMap) {
        BaseRequest request = new BaseRequest();
        request.setBaseUrl(config.getBaseUrl());
        request.setApiUri("/2/tools/industry/get/");

        request.setAccessToken(accessToken);

        request.setParamMap(paramMap);

        return RequestHandler.doGet(request);
    }
}
